package com.kandroid.ogles_triangledemo;

import android.annotation.SuppressLint;
import android.opengl.GLES30;
import android.opengl.Matrix;

import com.kandroid.ogles_triangledemo.utils.ShaderUtil;
import com.kandroid.ogles_triangledemo.widgets.MyTDView;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

/**
 * Created by Kandroid on 30/08/2017.
 */

public class Triangle {
    public static float[] mProjMatrix = new float[16];//4x4 投影矩阵
    public static float[] mVMatrix = new float[16];//摄像机位置朝向的参数矩阵
    public static float[] mMVPMatrix;//总变换矩阵

    private int mProgram;//着色器程序id
    private int muMVPMatrixHandle;//总变换矩阵引用
    private int maPositionHandle; //顶点位置属性引用
    private int maColorHandle; //顶点颜色属性引用
    private String mVertexShader;//顶点着色器代码脚本
    private String mFragmentShader;//片元着色器代码脚本
    private static float[] mMMatrix = new float[16];//具体物体的3D变换矩阵

    private FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
    private FloatBuffer mColorBuffer;//顶点颜色数据缓冲
    private int vCount = 0;
    public float xAngle = 0;//绕x轴旋转的角度

    public Triangle(MyTDView mv) {
        initVertexData();
        initShader(mv);
    }

    public void initVertexData()//初始化顶点数据
    {
        vCount = 3;
        final float UNIT_SIZE = 0.2f;
        float vertices[] = new float[]//顶点坐标数组
                {
                        -4 * UNIT_SIZE, 0, 0,
                        0, -4 * UNIT_SIZE, 0,
                        4 * UNIT_SIZE, 0, 0,
                };

        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        mVertexBuffer = vbb.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);

        float colors[] = new float[]
                {
                        0, 1, 1, 0,
                        0, 1, 1, 0,
                        0, 1, 1, 0
                };

        ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
        cbb.order(ByteOrder.nativeOrder());
        mColorBuffer = cbb.asFloatBuffer();
        mColorBuffer.put(colors);
        mColorBuffer.position(0);
    }

    @SuppressLint("NewApi")
    public void initShader(MyTDView mv) {
        mVertexShader = ShaderUtil.loadFromAssetsFile("vertex.sh", mv.getResources());
        mFragmentShader = ShaderUtil.loadFromAssetsFile("frag.sh", mv.getResources());
        mProgram = ShaderUtil.createProgram(mVertexShader, mFragmentShader);

        //Initialize the handles
        maPositionHandle = GLES30.glGetAttribLocation(mProgram, "aPosition");
        maColorHandle = GLES30.glGetAttribLocation(mProgram, "aColor");
        muMVPMatrixHandle = GLES30.glGetUniformLocation(mProgram, "uMVPMatrix");
    }

    @SuppressLint("NewApi")
    public void drawSelf() {
        GLES30.glUseProgram(mProgram);

        Matrix.setRotateM(mMMatrix, 0, 0, 0, 1, 0);
        Matrix.translateM(mMMatrix, 0, 0, 0, 1);
        Matrix.rotateM(mMMatrix, 0, xAngle, 1, 0, 0);
        GLES30.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, Triangle.getFinalMatrix(mMMatrix), 0);

        GLES30.glVertexAttribPointer(maPositionHandle, 3, GLES30.GL_FLOAT, false, 3 * 4, mVertexBuffer);
        GLES30.glVertexAttribPointer( maColorHandle, 4, GLES30.GL_FLOAT, false, 4 * 4, mColorBuffer);
        GLES30.glEnableVertexAttribArray(maPositionHandle);
        GLES30.glEnableVertexAttribArray(maColorHandle);
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vCount);
    }

    public static float[] getFinalMatrix(float[] spec) {
        mMVPMatrix = new float[16];
        Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, spec, 0);
        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
        return mMVPMatrix;
    }
}
